package com.yunyao.framework.audit;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yunyao.common.constant.enums.AuditStatusEnums;
import com.yunyao.common.constant.enums.DataDeletedStatus;
import com.yunyao.common.dto.audit.AuditFlowTypeEnums;
import com.yunyao.common.dto.audit.AuditResultEnums;
import com.yunyao.common.dto.audit.CreateAuditFlowDto;
import com.yunyao.common.exception.AuditException;
import com.yunyao.common.web.enums.ResultMsgEnum;
import com.yunyao.common.web.util.ConvertUtil;
import com.yunyao.dao.model.BamuPayment;
import com.yunyao.dao.model.BamuPaymentHistory;
import com.yunyao.dao.model.BamuReceiveHistory;
import com.yunyao.dao.service.bamu.IBamuPaymentHistoryService;
import com.yunyao.dao.service.bamu.IBamuPaymentService;
import com.yunyao.dao.service.bamu.IBamuReceiveHistoryService;
import com.yunyao.dao.service.bamu.IBamuReceiveService;
import com.yunyao.framework.dto.audit.ApprovalDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * 付款管理审批Handle
 * @author chenyejian
 * @date 2024-08-01
 */
@Slf4j
@Component
public class PaymentAuditHandle extends AbstractAuditFlowHandle {
    @Autowired
    private IBamuPaymentService iBamuPaymentService;
    @Autowired
    private IBamuPaymentHistoryService paymentHistoryService;

    @Transactional(rollbackFor = AuditException.class)
    public void submit(String bizId) throws AuditException {
        BamuPayment payment = iBamuPaymentService.getById(bizId);
        String name = payment.getReceiveTypeName();
        Integer status = payment.getStatus();
        String modelInfoReceiveId = defaultAuditModelInfo.getReceiveId();
        try {
            /**
             * 校验数据
             */
            checkSubmitData(payment);
            CreateAuditFlowDto createAuditFlowDto = creatFlow(modelInfoReceiveId,
                    AuditFlowTypeEnums.MODEL_NAME_PAYMENT.getType(), bizId, name,
                    String.valueOf(status));

            payment.setProcessInstanceId(createAuditFlowDto.getProcessInstanceId());
            payment.setDeploymentId(createAuditFlowDto.getDeploymentId());
            payment.setModelSchemeInfoId(createAuditFlowDto.getModelSchemeInfoId());
            payment.setProcessVersion(createAuditFlowDto.getProcessVersion());
            payment.setAuditStatus(String.valueOf(AuditStatusEnums.AUDIT.getType()));
            iBamuPaymentService.saveOrUpdate(payment);
        } catch (Exception e) {
            log.error("收款管理submit approval error", e);
            throw new AuditException(e.getMessage());
        }
    }

    public void approval(ApprovalDto approvalDto) throws AuditException {
        try {
            String bizId = approvalDto.getId();
            Boolean auditResult = approvalDto.getAuditResult();
            String auditResultStr = auditResult ? AuditResultEnums.AGREE.getKey() :
                    AuditResultEnums.REJECT.getKey();
            BamuPayment receive = iBamuPaymentService.getById(bizId);
            checkApprovalData(receive);
            boolean isEnd = executeFlow(receive.getProcessInstanceId(),
                    receive.getDeploymentId(), auditResultStr,
                    approvalDto.getAuditResultMsg(), approvalDto.getAuditFileList());
            if (!isEnd) {
                return;
            }
            if (auditResult) {
                /**
                 * 保存收款历史记录
                 */
                LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<BamuPaymentHistory>()
                        .eq(BamuPaymentHistory::getReceiveId, receive.getId())
                        .eq(BamuPaymentHistory::getIsDeleted, DataDeletedStatus.NO.getType());
                List<BamuPaymentHistory> historyList = paymentHistoryService.list(queryWrapper);
                if (historyList == null || historyList.size() == 0) {
                    BamuPaymentHistory history = new BamuPaymentHistory();
                    BeanUtils.copyProperties(receive, history);
                    history.setReceiveId(receive.getId());
                    paymentHistoryService.saveOrUpdate(history);
                }
                receive.setAuditStatus(ConvertUtil.null2String(AuditStatusEnums.AUDIT_SUCCESS.getType()));
            } else {
                receive.setAuditStatus(ConvertUtil.null2String(AuditStatusEnums.AUDIT_REJECT.getType()));
            }
            iBamuPaymentService.saveOrUpdate(receive);
        } catch (Exception e) {
            log.error("付款管理 approval error", e);
            throw new AuditException(e.getMessage());
        }

    }
    
    private void checkApprovalData(BamuPayment approvalData) throws AuditException {
        if (Objects.isNull(approvalData)) {
            throw new AuditException(ResultMsgEnum.NO_DATA);
        }
        String auditStatus = approvalData.getAuditStatus();
        if (AuditStatusEnums.AUDIT.getType() != Integer.parseInt(auditStatus)) {
            throw new AuditException(ResultMsgEnum.SUBMIT_AUDIT_STATUS_ERROR);
        }
        String processInstanceId = approvalData.getProcessInstanceId();
        if (StringUtils.isBlank(processInstanceId)) {
            throw new AuditException("processInstanceId is null");
        }
        String deploymentId = approvalData.getDeploymentId();
        if (StringUtils.isBlank(deploymentId)) {
            throw new AuditException("deploymentId is null");
        }
    }

    public boolean userIsAuditButton(String schemeInfoId, String processInstanceId) {
        try {
            return isCheckAudit(schemeInfoId, processInstanceId);
        } catch (Exception e) {
            log.info("付款管理userIsAuditButton error:{}", e.getMessage());
            return false;
        }
    }

    private void checkSubmitData(BamuPayment payment) throws AuditException {

        if (Objects.isNull(payment)) {
            throw new AuditException(ResultMsgEnum.NO_DATA);
        }

        String auditStatus = payment.getAuditStatus();
        if (AuditStatusEnums.AUDIT.getType() == Integer.parseInt(auditStatus)
                && AuditStatusEnums.AUDIT_SUCCESS.getType() == Integer.parseInt(auditStatus)
                && AuditStatusEnums.AUDIT_REJECT.getType() == Integer.parseInt(auditStatus)) {
            throw new AuditException(ResultMsgEnum.SUBMIT_AUDIT_STATUS_ERROR);
        }
    }
}
